package com.hugang.newfeature.optional;

import org.junit.Test;

import java.util.Optional;

/**
 * Optional类的使用：为了在程序中避免出现空指针异常而创建的。
 *
 * 常用的方法：ofNullable(T t)
 *           orElse(T other)
 * 1、创建Optional类对象的方法
 *      Optional.of(T t)：创建一个Optional的实例，t必须非空
 *      Optional.empty()：创建一个空的Optional实例
 *      Optional.ofNullable(T t)：t可以为null
 * 2、判断Optional容器中是否包含对象：
 *      boolean isPresent()：判断是否包含对象
 *      void ifPresent(Consumer<? super T> consumer)：如果有值，就执行Consumer接口的实现代码，并且该值会作为参数传给它
 * 3、获取Optional容器的对象
 *      T get()：如果调用对象包含值，返回该值，否则抛异常
 *      T orElse(T other)：如果有值则将其返回，否则返回指定的other对象。
 *      ...
 *
 * @author hg
 * @date 2020/6/26 22:22
 */
public class OptionalTest {

    /**
     * 1、创建Optional类对象的方法
     *      Optional.of(T t)：创建一个Optional的实例，t必须非空
     *      Optional.empty()：创建一个空的Optional实例
     *      Optional.ofNullable(T t)：t可以为null
     */
    @Test
    public void test1(){
        Girl girl = new Girl();
        girl = null;
        //of(T t)：保证t非空
//        Optional<Girl> optionalGirl = Optional.of(girl);
//        System.out.println(optionalGirl);
        System.out.println();
        //ofNullable(T t)：t可以为空
        Optional<Girl> girl1 = Optional.ofNullable(girl);
        //orElse(T t)：如果当前的Optional对象封装的t是非空的，则返回内部的t；如果t是空的，则返回orElse(T t)方法中的参数t
        Girl orElse = girl1.orElse(new Girl("赵丽颖"));
        System.out.println(orElse);
    }

    /**
     * 优化前
     * @param boy
     * @return
     */
    public String getGirlName(Boy boy){
        return boy.getGirl().getName();
    }

    /**
     * 优化后
     * @param boy
     * @return
     */
    public String getGirlName1(Boy boy){
        if (boy != null){
            if (boy.getGirl() != null){
                return boy.getGirl().getName();
            }
        }
        return null;
    }

    /**
     * 使用Optional类的getGirlName()
     * @param boy
     * @return
     */
    public String getGirlName2(Boy boy){
        Optional<Boy> optionalBoy = Optional.ofNullable(boy);

        Boy orElse = optionalBoy.orElse(new Boy(new Girl("迪丽热巴")));
        Girl girl = orElse.getGirl();
        Optional<Girl> optionalGirl = Optional.ofNullable(girl);
        Girl girl1 = optionalGirl.orElse(new Girl("古力娜扎"));
        return girl1.getName();

    }



    @Test
    public void test3(){
        //通常这样写，可能出现空指针异常
        Boy boy = new Boy();
//        String girlName = getGirlName(boy);
        String girlName = getGirlName1(boy);
        System.out.println(girlName);
    }

    @Test
    public void test4(){
        Boy boy = null;
        boy = new Boy();
        boy = new Boy(new Girl("苍老师"));
        String girlName2 = getGirlName2(boy);
        System.out.println(girlName2);
    }
}

class Boy{
    private Girl girl;

    @Override
    public String toString() {
        return "Boy{" +
                "girl=" + girl +
                '}';
    }

    public Girl getGirl() {
        return girl;
    }

    public void setGirl(Girl girl) {
        this.girl = girl;
    }

    public Boy() {
    }

    public Boy(Girl girl) {
        this.girl = girl;
    }
}

class Girl {
    private String name;

    public Girl(String name) {
        this.name = name;
    }

    public Girl() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Girl{" +
                "name='" + name + '\'' +
                '}';
    }
}
